/**
 * Copyright (c) 2020 kedacom
 * OpenATC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 * http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 **/
package com.openatc.agent.controller;

import com.openatc.agent.model.Role;
import com.openatc.agent.service.PermissionDao;
import com.openatc.agent.service.RoleDao;
import com.openatc.agent.service.RolePermissionDao;
import com.openatc.agent.service.impl.WebOperationCollector;
import com.openatc.agent.service.impl.WebOperationRecordExtractor;
import com.openatc.core.common.IErrorEnumImplOuter;
import com.openatc.core.model.RESTRetBase;
import com.openatc.core.util.RESTRetUtils;
import com.openatc.extend.common.aop.model.SysLog;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author kedacom
 * @ClassName: UserController
 * @Description:
 * @date 2019年11月3日 下午9:00:48
 */
@RestController
@RequestMapping("/auth/role")
public class RoleController {

    @Autowired
    protected PermissionDao permissionDao;

    @Autowired
    protected RolePermissionDao rolePermissionDao;

    @Autowired
    protected RoleDao roleDao;

    /**
     * @return RESTRetBase
     * @throws
     * @Title: getRoles
     * @Description:
     */
//    @RequiresPermissions({"sys:auth:role:view"})
    @GetMapping("")    //查询所有角色
    public RESTRetBase getRoles() {
        List<Role> roles = roleDao.findAll();
        return RESTRetUtils.successObj(roles);
    }


    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @PostMapping("")
    @RequiresRoles(value = {"admin","superadmin"},logical = Logical.OR)
    public RESTRetBase addRole(@RequestBody Role sysRole) {
        // 若是超级管理员角色，不能添加
        if ("superadmin".equals(sysRole.getName())) {
            return RESTRetUtils.errorObj(false,IErrorEnumImplOuter.E_3021);
        }
        // 先查询角色名字是否重复
        Role role = roleDao.getRoleByUserName(sysRole.getName());
        if (role != null) {
            return RESTRetUtils.errorObj(false, IErrorEnumImplOuter.E_3020);
        }

        return RESTRetUtils.successObj(roleDao.save(sysRole));
    }

    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @DeleteMapping("/{roleId}")
    @RequiresRoles(value = {"admin","superadmin"},logical = Logical.OR)
    public RESTRetBase delRole(@PathVariable int roleId) {
        try{
            Role role = roleDao.findById(roleId);
            if ("superadmin".equals(role.getName())) {
                return RESTRetUtils.errorObj(false, IErrorEnumImplOuter.E_3010);
            }
            if ("admin".equals(role.getName())) {
                return RESTRetUtils.errorObj(false, IErrorEnumImplOuter.E_3022);
            }
            roleDao.deleteById(roleId);
        }
        catch (Exception e){
            return RESTRetUtils.errorObj("9999",e.getMessage(),"/auth/role/" + roleId,null);
        }
        return RESTRetUtils.successObj();
    }

    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @PutMapping()
    @RequiresRoles(value = {"admin","superadmin"},logical = Logical.OR)
    public RESTRetBase putRole(@RequestBody Role sysRole) {
        Role dbrole = roleDao.findById(sysRole.getId());
        // 不是管理员，要修改为管理员
        if (!"superadmin".equals(dbrole.getName()) && "superadmin".equals(sysRole.getName())) {
            return RESTRetUtils.errorObj(false, IErrorEnumImplOuter.E_3021);
        }

        // 是管理员，要修改名称
        if ("superadmin".equals(dbrole.getName()) && !"superadmin".equals(sysRole.getName())) {
            return RESTRetUtils.errorObj(false, IErrorEnumImplOuter.E_3010);
        }
        if ("admin".equals(dbrole.getName()) && !"admin".equals(sysRole.getName())) {
            return RESTRetUtils.errorObj(false, IErrorEnumImplOuter.E_3010);
        }
        // 已有该角色，还要把其他的角色改为当前角色
        if (!sysRole.getName().equals(dbrole.getName())) {
            int role = roleDao.getCountByName(sysRole.getName());
            if (role != 0) {
                return RESTRetUtils.errorObj(false, IErrorEnumImplOuter.E_3020);
            }
        }
        return RESTRetUtils.successObj(roleDao.save(sysRole));
    }

    @GetMapping("/{roleId}")
    public RESTRetBase getRole(@PathVariable int roleId) {
        return RESTRetUtils.successObj(roleDao.findById(roleId) );
    }

    @PutMapping("/{roleId}/permissions")
    @RequiresRoles(value = {"admin","superadmin"},logical = Logical.OR)
    public RESTRetBase putRolePermissions(@PathVariable int roleId, @RequestBody List<Integer> permissions) {
        // 管理员或超管的权限不能被修改
        Role role = roleDao.findById(roleId);
        if ("admin".equals(role.getName()) || "superadmin".equals(role.getName())) {
            return RESTRetUtils.errorObj(IErrorEnumImplOuter.E_3023);
        }

        rolePermissionDao.deleteAllByRoleId(roleId);

        for ( Integer permission : permissions){
            rolePermissionDao.updateRoleByUser(roleId, permission);
        }

        return RESTRetUtils.successObj();
    }

    @GetMapping("/{roleId}/permissions")
    public RESTRetBase getRolePermissions(@PathVariable int roleId) {
        return RESTRetUtils.successObj( permissionDao.findPermissionByRoleId(roleId) );
    }

}
